#/bin/bash +e

# echo welcome message for Charmm patching
echo \
"---------------------------------------------------------

Patching eef1 for CHARMM

---------------------------------------------------------"

# check if csh exists so that you can run install.com 
CHECK_CSH () {
csh=`which csh`
if [  x"$csh" = x ] || [ ! -x "$csh" ]; 
then
    echo \
"---------------------------------------------------------
Cannot find csh on this system, unable to run install.com for CHARMM. Exiting...
---------------------------------------------------------"
    exit
else 
    echo \
"---------------------------------------------------------
Found csh in $csh.
---------------------------------------------------------"
fi
}


#locate charmm_main.src , get charmm version and base dir.
GET_CHARMM_SRC (){
local charmm_dir=()
local charmm_version=()
for f in `locate charmm_main.src`
do 
    ext=${f##*.}
    basename=${f##*/}
    dir=${f%/*}
   if [ $basename == 'charmm_main.src' ]; then
        version=`grep "Version" $f`
        version=${version##*Version (}
        version=${version%)*}
        charmm_version+=($version)
        charmm_dir+=(${dir%/*/*})
   fi
done
if [ ${#charmm_dir[@]} == 0 ]; then
    echo "Cannot find CHARMM source code on this system, unable to apply patch to CHARMM."
    echo -n "Indicate a possible location to search for it? "
    read charmmdir
    #check if charmm_main.src exists under indicated folder.
    foundsrc=`find $charmmdir -name charmm_main.src`
    if [ x"$foundsrc" = x ] || [ "${foundsrc##*/}" != charmm_main.src ]; then
        echo "Cannot find CHAMM in your given location, try another location[Y/N]?"
        read confirm
        if [ x"$confirm" = x ] || [[ $confirm =~ ^[Yy]{1}[Ee]{0,1}[Ss]{0,1}$ ]] ; then
            GET_CHARMM_SRC
        else 
            echo "Exiting..."
            exit 0
        fi 
    else
        for f in $foundsrc
        do 
            ext=${f##*.}
            basename=${f##*/}
            dir=${f%/*}
            if [ $basename == 'charmm_main.src' ]; then
                version=`grep "Version" $f`
                version=${version##*Version (}
                version=${version%)*}
                charmm_version+=($version)
                charmm_dir+=(${dir%/*/*})
            fi   
        done
    fi
fi 
if [ ${#charmm_dir[@]} -gt 1 ]; then 
    selected=-1
    while [ "$selected" -lt 0 ] || [ $selected -ge "${#charmm_dir[@]}" ]; do
            echo \
"---------------------------------------------------------
Found CHARMM source code package in the following locations:
---------------------------------------------------------
"
             for i in $(seq 0 $((${#charmm_dir[@]} - 1)))
             do
                echo "[$i] Version: ${charmm_version[$i]} Path: ${charmm_dir[$i]}"
             done
             
            echo -n "Select a package from above to apply patch [Default: 0]:"
            read selected
            if [ x"$selected" = x ]; then 
             selected=0
            fi
            if [[ ! $selected =~ ^[0-9]+ ]]; then
            selected=-1
            fi
    done 
    echo -n "Selected [$selected] ${charmm_dir[$selected]},Correct?[Y/N]:"
    read confirm
    if [ x"$confirm" = x ] || [[ $confirm =~ ^[Yy]{1}[Ee]{0,1}[Ss]{0,1}$ ]] ; then
        echo "Going to use following CHARMM source code: ${charmm_dir[$selected]}"
        echo "---------------------------------------------------------"
        charmmdir=${charmm_dir[$selected]}
    else 
        GET_CHARMM_SRC 
    fi  
else 
    echo \
"---------------------------------------------------------
Found CHARMM source code package in the following location:
---------------------------------------------------------
"
    echo "Version: ${charmm_version[0]} Path: ${charmm_dir[0]} "
    charmmdir=${charmm_dir[0]}
fi 

}

# Patch location 

GET_PATCH_LOCATION (){
echo -n "Patch to the orignal location?[Y/N]:"
read confirm
if [ ! x"$confirm" = x ] && [[ ! $confirm =~ [Yy]{1}[Ee]{0,1}[Ss]{0,1} ]] ; then
    echo -n "Input a location to save the source files:"
    read patch_location
    while [ x"$patch_location" = x ] || [ ! -d ${patch_location} ]; do
        echo -n "Do not exists directory ${patch_location}, please indicate another location:"
        read patch_location
    done
else 
    patch_location=${charmmdir}
fi 
echo "---------------------------------------------------------"
}
# Get charmm size
GET_CHARMM_SIZE () {
    defautlcharmmsize=medium
    echo "Input a CHARMM size you want to compile:"
    echo "---------------------------------------------------------"
    echo "Available Size: huge, xxlarge, xlarge, large, 
                medium, small, xsmall, reduce"
    echo -n "[default: medium]:"
    read charmmsize 
    if [ x"$charmmsize" = x ]; then
        charmmsize="$defautlcharmmsize"
    fi
    case $charmmsize in
      huge) ;;
      xxlarge) ;;
      xlarge) ;;
      large) ;;
      medium) ;;
      small) ;;
      xsmall) ;;
      reduce) ;;
      *) echo "$charmmsize is not a correct selection."
      GET_CHARMM_SIZE
      ;;
    esac
    echo "---------------------------------------------------------"
}
# Check system environment
CHECK_ARCH () {
    systemtype=`uname -s`
    machinetype=`uname -m`
}
CHECK_COMPILER () {
    #check if gnu compiler exists.
    compilers=()
    gfortran=`which gfortran`
    if [ x"$gfortran" != x ]; then
        compilers+=($gfortran)
    fi
    #check if intel compiler exists.
    ifort=`which ifort`
    if [ x"$ifort" != x ]; then
        compilers+=($ifort)
    fi
    #check for obsolete f77 or g77?
    if [ ${#compilers[@]} -gt 1 ]; then
        selected=-1
        while [ $selected -lt 0 ] || [ $selected -ge ${#compilers[@]} ]; 
        do 
            echo \
"Has follwing Fortran compilers:
---------------------------------------------------------"
            for i in $(seq 0 $((${#compilers[@]} - 1)))
            do
               echo "[$i] ${compilers[i]}"
            done
            echo "---------------------------------------------------------"
            echo -n "Choose one to be used to compile CHARMM [Default:0]:"
            read selected
            if [ x"$selected" = x ]; then 
                selected=0
            fi
            if [[ ! $selected =~ ^[0-9]+$ ]]; then
                selected=-1
            fi
        done
        echo -n "Selected [$selected] ${compilers[$selected]},Correct?[Y/N]:"
        read confirm
        if [ x"$confirm" = x ] || [[ $confirm =~ ^[Yy]{1}[Ee]{0,1}[Ss]{0,1}$ ]] ; then
            echo "Going to use Compiler: ${compilers[$selected]}"
            compiler=${compilers[$selected]}
        else 
            CHECK_COMPILER 
        fi  
    elif [ ${#compilers[@]} = 1 ]; then
        echo "Use ${compilers[0]} as the fortran compiler."
        compiler=${compilers[0]}
    else 
        echo "No fortran compiler found on this machine."
        exit 0
    fi 
}
CHECK_FC_WORKS () {
    if [ -z "$1" ]                           # Is parameter #1 zero length?
    then
        echo "-Parameter #1 is zero length.-"  # Or no parameter passed.
        return 0
    fi
    fc=$1
    echo \
"       program hello
          print *, \"Hello World from $fc. \"
       end program hello
" > tmp.test.f
    $fc tmp.test.f -o tmp.test
    tmp.test
    rm tmp.test.f
    rm tmp.test 
    return 1
}

SETUP_FLAGS () {
    if [ $machinetype = "x86_64" ]; then
        machinetag=x86_64
    else 
        machinetag=""
    fi
    if [ "$sytemtype" =  "osx" ]; then
        archtag=osx
    elif [[ "$systemtype" =~ [Ll]inux ]]; then
        if [ "${compiler##*/}" = "gfortran" ]; then
            archtag=gnu
        elif [ "${compiler##*/}" = "ifort" ]; then
            archtag=em64t
            if [ $machinetype = "x86_64" ]; then
                machinetag=" ifort"
            else 
                machinetag=" ifort"
            fi
        else
            archtag=gnu
        fi
    else
        archtag=gnu
    fi
    chflags="${archtag} ${charmmsize:-medium} ${machinetag} ${compilertag:-""} ${additionaltag:-""}"

}

COMPILE_CHARMM () {
    # copy source file into destination folder
    if [ "${charmmdir}" != "${patch_location}" ]; then
        echo "Copying files from $charmmdir to ${patch_location}..."
        exit 0
        cp -r ${charmmdir}/* ${patch_location}
    fi
    # apply patch files 
    cp ${patch_location}/source/misc/eef1.src ${patch_location}/source/misc/eef1.src.bak
    cp eef1.src ${patch_location}/source/misc/eef1.src
    cp ${patch_location}/source/fcm/eef1.fcm ${patch_location}/source/fcm/eef1.fcm.bak
    cp eef1.fcm ${patch_location}/source/fcm/eef1.fcm
    cp ${patch_location}/source/nbonds/enbfast.src ${patch_location}/source/nbonds/enbfast.src.bak
    cp enbfast.src ${patch_location}/source/nbonds/enbfast.src
    
    # clean up before install 
    rm -rf ${patch_location}/build/$archtag
    rm -rf ${patch_location}/lib/$archtag
    rm -f ${patch_location}/tool/prefx_$archtag
    # run install.com 
    echo "Run install.com $chflags ..."
    cd ${patch_location}
    # setup csh compiler environment?
    msg=`$csh install.com $chflags`
#    msg=`./install.com $chflags`
    error=${msg##*NOT produced.}
    echo $msg
    echo $error
    if [ "$error" != "$msg" ]; then
        error=${error#*Check}
        error="${error%%for installation errors*}"
        grep "no \|No \|Not \|not \|denied\|warning" $error | while read line 
        do
            echo "$line"
        done
        echo "Compile Patched CHARMM failed. Check $error for more details."
        # echo hints for possible mistake?
        exit 1
    else
        echo "Compiled CHARMM sucessfully."
    fi 
}

GET_CHARMM_SRC
GET_PATCH_LOCATION
GET_CHARMM_SIZE
CHECK_CSH
CHECK_ARCH
CHECK_COMPILER
SETUP_FLAGS
COMPILE_CHARMM
echo \
"---------------------------------------------------------
Finished Patching.
Please add the binary file: ${patch_location}/exec/${archtag}/charmm into your binary search PATH. You can rename this file to any convenient name to differentiate it from the original CHARMM.
"
exit 0
